/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package exatrez.manager;

import com.google.inject.Inject;
import com.wideplay.warp.persist.Transactional;
import exatrez.dao.DepartmentDAO;
import exatrez.dao.RefShipVisitHeaderDAO;
import exatrez.dao.RefShipVisitMatchDAO;
import exatrez.dao.RefShipVisitMatchSubDAO;
import exatrez.dao.RefShipVisitSubDAO;
import exatrez.dao.ShipVisit3CounterDAO;
import exatrez.dao.ShipVisit3DAO;
import exatrez.dao.ShipVisit3FileDAO;
import exatrez.dao.ShipVisit3FileTempDAO;
import exatrez.dao.ShipVisit3HistoryDAO;
import exatrez.dao.ShipVisit3SubDAO;
import exatrez.dao.ShipVisit3SubExtendDAO;
import exatrez.dao.ShipVisit3SubExtendFileDAO;
import exatrez.dao.ShipVisit3SubExtendFileTempDAO;
import exatrez.model.InfoAudit;
import exatrez.model.RefShipVisitHeader;
import exatrez.model.RefShipVisitMatch;
import exatrez.model.RefShipVisitMatchSub;
import exatrez.model.RefShipVisitSub;
import exatrez.model.ShipVisit3;
import exatrez.model.ShipVisit3Counter;
import exatrez.model.ShipVisit3File;
import exatrez.model.ShipVisit3FileTemp;
import exatrez.model.ShipVisit3History;
import exatrez.model.ShipVisit3Sub;
import exatrez.model.ShipVisit3SubExtend;
import exatrez.model.ShipVisit3SubExtendFile;
import exatrez.model.ShipVisit3SubExtendFileTemp;
import exatrez.model.User;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Admin
 */
public class ShipVisit3Manager {
    
    private static Logger LOG = LoggerFactory.getLogger(ShipVisit3Manager.class);
    
    @Inject
    protected com.google.inject.Provider<Session> sessionProvider;
    @Inject
    private ShipVisit3CounterDAO shipVisit3CounterDAO;
    @Inject
    private ShipVisit3DAO shipVisit3DAO;
    @Inject
    private ShipVisit3SubDAO shipVisit3SubDAO;
    @Inject
    private ShipVisit3SubExtendDAO shipVisit3SubExtendDAO;
    @Inject
    private ShipVisit3HistoryDAO shipVisit3HistoryDAO;
    @Inject
    private ShipVisit3FileTempDAO fileTempDAO;
    @Inject
    private ShipVisit3SubExtendFileTempDAO subFileTempDAO;
    @Inject
    private ShipVisit3FileDAO shipVisit3FileDAO;
    @Inject
    private ShipVisit3SubExtendFileDAO shipVisit3SubExtendFileDAO;
    @Inject
    private RefShipVisitHeaderDAO refHeaderDAO;
    @Inject
    private RefShipVisitSubDAO refSubHeaderDAO;
    @Inject
    private RefShipVisitMatchDAO matchDAO;
    @Inject
    private RefShipVisitMatchSubDAO subMatchDAO;
    @Inject
    private DepartmentDAO departmentDAO;
    
    private static String SUCCESS = "success";
    private static String FAIL = "fail";
    
    public List<RefShipVisitMatch> getListShipVisitMatch(Integer departmentId){
        StringBuilder query = new StringBuilder("SELECT a FROM RefShipVisitMatch a WHERE a.department.active = 'Y' ");
        if(departmentId != null){
            query.append("and a.department.departmentId = :departmentId ");            
        }
        query.append("order by a.shipVisitHeader.orderFlag asc ");
        
        Query q = sessionProvider.get().createQuery(query.toString());
        if(departmentId != null){
            q.setParameter("departmentId", departmentId);
        }
        return q.list();
    }
    
    public List<ShipVisit3Counter> getListCounter(User user, String year, String departmentId){
        StringBuilder sb = new StringBuilder("select s from ShipVisit3Counter s, User u ")
                .append("where s.user = u ");
        
        Session session = sessionProvider.get();
        
        if(user != null){
            sb.append("and s.user.userId = :userId ");
        }
        if(year != null){
            sb.append("and s.year = :year ");
        }
        if(departmentId != null){
            sb.append("and u.department.departmentId = :departmentId ");
        }
        sb.append("order by s.infoAudit.createDate");
        
        Query query = session.createQuery(sb.toString());
        if(user != null){
            query.setParameter("userId", user.getUserId());
        }
        if(year != null){
            query.setParameter("year", year);
        }
        if(departmentId != null){
            query.setParameter("departmentId", Integer.parseInt(departmentId));
        }
        return query.list();
    }
    
    @Transactional
    public String saveOrUpdateVisitCounter(ShipVisit3Counter visitCounter){
        String result = SUCCESS;
        LOG.info("ShipVisit3Counter.Id :"+visitCounter.getSv3CounterId());
        try{
            shipVisit3CounterDAO.saveOrUpdate(visitCounter);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }    
    
    public List<ShipVisit3> getListVisitKIV(User user, String year){
        StringBuilder sb = new StringBuilder("select s from ShipVisit3 s ")
                .append("where s.user.userId  = :userId and s.deleted = 'N' and s.status = 'K' ");
        if(StringUtils.isNotBlank(year)){
            sb.append("and year(s.dateVisit) = :year ");
        }
        sb.append("order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", user.getUserId());
        if(StringUtils.isNotBlank(year)){
            query.setInteger("year", Integer.parseInt(year));
        }
        
        return query.list();
    }
    
    public List<ShipVisit3> getListVisitApprove(User user, String year){
        StringBuilder sb = new StringBuilder("select s from ShipVisit3 s ")
                .append("where s.user.userId  = :userId and s.deleted = 'N' and s.status = 'A' ");
        if(StringUtils.isNotBlank(year)){
            sb.append("and year(s.dateVisit) = :year ");
        }
        sb.append("order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", user.getUserId());
        if(StringUtils.isNotBlank(year)){
            query.setInteger("year", Integer.parseInt(year));
        }
        
        return query.list();
    }
    
    public List<ShipVisit3> getListVisitReject(User user, String year){
        StringBuilder sb = new StringBuilder("select s from ShipVisit3 s ")
                .append("where s.user.userId  = :userId and s.deleted = 'N' and s.status = 'R' ");
        if(StringUtils.isNotBlank(year)){
            sb.append("and year(s.dateVisit) = :year ");
        }
        sb.append("order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", user.getUserId());
        if(StringUtils.isNotBlank(year)){
            query.setInteger("year", Integer.parseInt(year));
        }
        
        return query.list();
    }
    
    @Transactional
    public String saveForm(ShipVisit3 sv3, List<ShipVisit3Sub> sub, List<ShipVisit3FileTemp> listFileTemp, List<ShipVisit3SubExtendFileTemp> listSubFileTemp){
        String result = SUCCESS;
        try{
            shipVisit3DAO.save(sv3);
//            LOG.debug("sub.size :"+sub.size());
            for (ShipVisit3Sub sv3s : sub) {
                sv3s.setShipVisit3(sv3);
                shipVisit3SubDAO.save(sv3s);
//                LOG.debug("getListSV3SubExtend.size :"+sv3s.getListSV3SubExtend().size());
                for (ShipVisit3SubExtend subExtend : sv3s.getListSV3SubExtend()) {
//                    LOG.debug("subExtend Id:"+subExtend.getShipVisit3SubExtId()+", subId :"+subExtend.getShipVisitSub().getRefShipVisitSubId());
                    for (ShipVisit3SubExtendFileTemp fileTemp : listSubFileTemp) {
//                        LOG.debug("fileTemp Id:"+fileTemp.getShipVisit3SubExtFileTempId()+", subId :"+fileTemp.getShipVisitSub().getRefShipVisitSubId());
                        if(fileTemp.getShipVisitSub().getRefShipVisitSubId().equals(subExtend.getShipVisitSub().getRefShipVisitSubId())){
//                            LOG.debug("match :"+subExtend.getShipVisitSub()+", Id :"+subExtend.getShipVisit3SubExtId());
                            ShipVisit3SubExtendFile file = new ShipVisit3SubExtendFile();
                            file.setContentType(fileTemp.getContentType());
                            file.setDeleted(fileTemp.getDeleted());
                            file.setDocumentPath(fileTemp.getDocumentPath());
                            file.setInfoAudit(fileTemp.getInfoAudit());
                            file.setTitle(fileTemp.getTitle());
                            file.setShipVisit3SubExtend(subExtend);
                            shipVisit3SubExtendFileDAO.saveOrUpdate(file);
                            subFileTempDAO.delete(fileTemp);
                        }
                    }
                }
            }
            
            // for doc upload
            for (ShipVisit3FileTemp fileTemp : listFileTemp) {
                ShipVisit3File file = new ShipVisit3File();
                file.setContentType(fileTemp.getContentType());
                file.setDeleted(fileTemp.getDeleted());
                file.setDocumentPath(fileTemp.getDocumentPath());
                file.setInfoAudit(fileTemp.getInfoAudit());
                file.setShipVisit3(sv3);
                file.setTitle(fileTemp.getTitle());
                shipVisit3FileDAO.saveOrUpdate(file);
                fileTempDAO.delete(fileTemp);
            }
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String reSubmitForm(ShipVisit3 sv3, ShipVisit3Counter sv3Counter){
        String result = SUCCESS;
        try{
            shipVisit3DAO.saveOrUpdate(sv3);
            shipVisit3CounterDAO.saveOrUpdate(sv3Counter);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String updateForm(ShipVisit3 sv3){
        String result = SUCCESS;
        try{
            shipVisit3DAO.update(sv3);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String updateSVSub(ShipVisit3Sub shipVisit3Sub){
        String result = SUCCESS;
        try{
            shipVisit3SubDAO.update(shipVisit3Sub);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String updateSVSubExtend(ShipVisit3SubExtend shipVisit3SubExtend){
        String result = SUCCESS;
        try{
            shipVisit3SubExtendDAO.update(shipVisit3SubExtend);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    public List<ShipVisit3> getListStaffKIV(){
        StringBuilder sb = new StringBuilder("select s from ShipVisit3 s ")
                .append("where s.deleted = 'N' and s.status = 'K' and s.workflow = 'T' order by s.infoAudit.createDate desc");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString());
        
        return query.list();
    }
    
    @Transactional
    public String approval(ShipVisit3 sv3, ShipVisit3Counter sv3Counter, ShipVisit3History sv3History){
        String result = SUCCESS;
        try{
            shipVisit3DAO.saveOrUpdate(sv3);
            if(sv3Counter != null){
                shipVisit3CounterDAO.saveOrUpdate(sv3Counter);
            }
            if(sv3History != null){
                shipVisit3HistoryDAO.save(sv3History);
            }
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace();//for development use only
            result = FAIL;
        }
        return result;
    }
    
    public List<ShipVisit3FileTemp> getListFiletmp(String staffId){
        StringBuilder sb = new StringBuilder("select s from ShipVisit3FileTemp s ")
                .append("where s.deleted = 'N' and s.user.userId = :userId");
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", staffId);
        
        return query.list();
    }
    
    @Transactional
    public String saveorUpdateFileTemp(ShipVisit3FileTemp visitFiletmp){
        String result = SUCCESS;
        try{
            fileTempDAO.saveOrUpdate(visitFiletmp);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    public List<ShipVisit3SubExtendFileTemp> getListFileSubtmp(String staffId, String refSubId){
        StringBuilder sb = new StringBuilder("select s from ShipVisit3SubExtendFileTemp s ")
                .append("where s.deleted = 'N' and s.user.userId = :userId ");
        if(StringUtils.isNotBlank(refSubId)){
            sb.append("and s.shipVisitSub.refShipVisitSubId = :subId ");
        }
        
        Session session = sessionProvider.get();
        
        Query query = session.createQuery(sb.toString()).setParameter("userId", staffId);
        if(StringUtils.isNotBlank(refSubId)){
            query.setParameter("subId", Integer.parseInt(refSubId));
        }
        
        return query.list();
    }
    
    @Transactional
    public String saveorUpdateFileSubTemp(ShipVisit3SubExtendFileTemp visitFileSubtmp){
        String result = SUCCESS;
        try{
            subFileTempDAO.saveOrUpdate(visitFileSubtmp);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String saveorUpdateFile(ShipVisit3File visitFile){
        String result = SUCCESS;
        try{
            shipVisit3FileDAO.saveOrUpdate(visitFile);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String saveorUpdateFileSub(ShipVisit3SubExtendFile visitSEFile){
        String result = SUCCESS;
        try{
            shipVisit3SubExtendFileDAO.saveOrUpdate(visitSEFile);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
//    for admin used only
    
    @Transactional
    public String saveorUpdateRefHeader(RefShipVisitHeader header){
        String result = SUCCESS;
        try{
            refHeaderDAO.saveOrUpdate(header);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String saveorUpdateRefSubHeader(RefShipVisitSub subHeader){
        String result = SUCCESS;
        try{
            refSubHeaderDAO.saveOrUpdate(subHeader);
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
    @Transactional
    public String saveorUpdateMatchHeader(List<RefShipVisitMatch> listRemove, List<String> listAdd, User user, String departmentId){
        String result = SUCCESS;
        try{
            for (RefShipVisitMatch m : listRemove) {
                for (RefShipVisitMatchSub s : m.getListAllMatchSub()) {
                    subMatchDAO.delete(s);
                }
                matchDAO.delete(m);
            }
            for (String s : listAdd) {
                RefShipVisitMatch match = new RefShipVisitMatch();
                match.setShipVisitHeader(refHeaderDAO.findById(Integer.parseInt(s)));
                match.setDepartment(departmentDAO.findById(Integer.parseInt(departmentId)));
                InfoAudit ia = new InfoAudit();
                ia.setCreateId(user);
                ia.setCreateDate(new Date());
                match.setInfoAudit(ia);
                matchDAO.saveOrUpdate(match);
            }
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }        
        return result;
    }
    
    public RefShipVisitMatch getRefMatch(String departmentId, String headerId){
        RefShipVisitMatch match = null;
        try{
            StringBuilder sb = new StringBuilder("select s from RefShipVisitMatch s ");
            sb.append("where s.department.departmentId = :deptId ");
            sb.append("and s.shipVisitHeader.refShipVisitHeaderId = :headerId ");

            Session session = sessionProvider.get();

            Query query = session.createQuery(sb.toString());
            query.setParameter("deptId", Integer.parseInt(departmentId));
            query.setParameter("headerId", Integer.parseInt(headerId));
            
            match = (RefShipVisitMatch) query.uniqueResult();
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
        }
        return match;
    }
    
    @Transactional
    public String saveUpdateSubMatch(List<RefShipVisitMatchSub> listRemove, List<String> listAdd, RefShipVisitMatch parent, User user){
        String result = SUCCESS;
        try{
            for (RefShipVisitMatchSub ms : listRemove) {
                ms.setShipVisitMatch(null);
                ms.setShipVisitSub(null);
                subMatchDAO.delete(ms);
            }
            for (String idSub : listAdd) {
                RefShipVisitSub sub = refSubHeaderDAO.findById(Integer.parseInt(idSub));
                RefShipVisitMatchSub rsvms = new RefShipVisitMatchSub();
                rsvms.setShipVisitMatch(parent);
                rsvms.setShipVisitSub(sub);
                InfoAudit ia = new InfoAudit();
                ia.setCreateId(user);
                ia.setCreateDate(new Date());
                rsvms.setInfoAudit(ia);
                
                subMatchDAO.saveOrUpdate(rsvms);
            }
        }catch(Exception ex){
            LOG.error(ex.getMessage());
            ex.printStackTrace(); //for development use only
            result = FAIL;
        }
        return result;
    }
    
}
